using System.Collections;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;

public class ZooCharacterController : MonoBehaviour
{
    public static ZooCharacterController instance;
    public bool canMove;

    [SerializeField]
    float movSpeed;
    [SerializeField]
    float jumpStrength;
    [SerializeField] 
    float coyoteTime;
    [SerializeField] 
    float jumpCooldown;
    [SerializeField]
    Animator kiaraAnim; 
    [SerializeField]
    Transform kiaraSprite;
    [SerializeField]
    Transform camera;
    [SerializeField]
    Vector2 cameraOffset;
    [SerializeField]
    ParticleSystem landPart;


    Rigidbody rb;
    bool grounded;
    bool left;
    bool right;
    float lastGroundedTime;
    float lastJumpTime;
    bool jumpStarted;
    Vector3 startPos;

    private void Awake()
    {
        if (ZooCharacterController.instance == null)
        {
            instance = this;
        }
        else
        {
            Destroy(gameObject);
        }
    }

    public void StopChar()
    {
        canMove = false;
        rb.isKinematic = true;
    }

    public void ResetPos()
    {
        transform.position = startPos;
        canMove = true;
        rb.isKinematic = false;
    }
    bool CanJump()
    {
        bool coyoteAllowed = Time.time - lastGroundedTime <= coyoteTime;
        if (grounded) {coyoteAllowed = true;}
        bool cooldownReady = Time.time - lastJumpTime >= jumpCooldown;
        return coyoteAllowed && cooldownReady;
    }

    private void Start()
    {
        rb = GetComponent<Rigidbody>();
        canMove = false;
        startPos = transform.position;
        rb.isKinematic = true;
    }

    void Update()
    {
        if (canMove)
        {
            GetInput();
        }
    }

    private void FixedUpdate()
    {
        RaycastForGround();
        CharacterMovement();
        CameraPlacement();
    }

    void CameraPlacement()
    {
        Vector3 camPos = new Vector3(transform.position.x + cameraOffset.x, transform.position.y + cameraOffset.y, camera.transform.position.z);
        camera.transform.position = camPos;
    }

    void CharacterMovement()
    {
        if (!left && !right)
        {
            kiaraAnim.SetBool("Moving", false);
            Move(Vector2.zero);
        }
        else if (right)
        {
            if (left)
            {
                kiaraAnim.SetBool("Moving", false);
                Move(Vector2.zero);
            }
            else
            {
                kiaraAnim.SetBool("Moving", true);
                Move(Vector2.right);
                kiaraSprite.rotation = Quaternion.Euler(0, 0, 0);
            }
        }
        else if (left)
        {
            kiaraAnim.SetBool("Moving", true);
            Move(Vector2.left);
            kiaraSprite.rotation = Quaternion.Euler(0, 180, 0);
        }
    }

    void RaycastForGround()
    {
        if (Physics.Raycast(transform.position, Vector3.down, 1f))
        {
            if (!grounded)
            {
                grounded = true;
                kiaraAnim.SetBool("Grounded", grounded);
                Invoke("NormalizeAnim", 0.25f);
                landPart.Play();
                ZooMusicManager.Instance.PlaySFX(2);
            }
        }
        else
        {
            if (grounded)
            {
                grounded = false;
                lastGroundedTime = Time.time;
                kiaraAnim.SetBool("Grounded", grounded);
            }
        }
    }

    void GetInput()
    {
        if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A))
        {
            left = true;
        }
        else { left = false; }

        if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D))
        {
            right = true;
        }
        else { right = false; }

        if ((Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.W)) && CanJump())
        {
            kiaraAnim.SetTrigger("Jump");
            jumpStarted = true;
        }

        if ((Input.GetKeyUp(KeyCode.Space) || Input.GetKeyUp(KeyCode.W)) && jumpStarted)
        {
            StartCoroutine(Jump());
        }
    }

    void Move(Vector2 dir)
    {
        rb.linearVelocity = new Vector3(dir.x * movSpeed, rb.linearVelocity.y, 0);
    }

    IEnumerator Jump()
    {
        jumpStarted = false;
        lastJumpTime = Time.time;
        rb.linearVelocity = Vector3.zero;
        rb.AddForce(jumpStrength * Vector2.up);
        ZooMusicManager.Instance.PlaySFX(1);
        yield return new WaitForSeconds(0.15f);
        kiaraAnim.SetTrigger("Air");
        yield return null;
    }

    void NormalizeAnim()
    {
        kiaraAnim.SetTrigger("Normal");
    }
}
